using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Collections;
using System.Diagnostics;
using System.IO;

namespace PopLava.Tools
{
    public partial class ActionBuilder : Form
    {
        private XmlDocument g_xmlDocument;
        private DataTable g_dt = new DataTable();
        private string g_sTileName = String.Empty;
        private string g_sCurrentViewID = String.Empty;
        private List<string> g_listOfActions = new List<string>();

        public ActionBuilder(string sTileName, ref XmlDocument xmlSavedSettings, string sCurrentViewID)
        {
            InitializeComponent();
            g_sTileName = sTileName;
            g_xmlDocument = xmlSavedSettings;
            g_sCurrentViewID = sCurrentViewID;
            InitActionDDL();
            InitDataGrid();
            LoadTilesSavedActions();
        }
        /// <summary>
        /// Crawl the AutoIt directory and grab the file names of all the AutoIt .au3 files
        /// This gets called every time we open the dialog so the global bar is reset and 
        /// we automatically update the DDL to match whats in the directory.
        /// </summary>
        private void InitActionDDL()
        {
            string sPathToActions = "AutoIt\\Scripts";
            //
            // Sanity check
            //
            if (Directory.Exists(sPathToActions))
            {
                List<string> listOfActions = new List<string>(Directory.GetFiles(sPathToActions, "*.au3", SearchOption.TopDirectoryOnly));// Many other aspects of code rely on scripts being located in one folder.
                listOfActions.Add("Copy String To Clipboard");
                listOfActions.Add("Open View");
                listOfActions.Add("Sleep");
                listOfActions.Sort();
                foreach (string s in listOfActions)
                {
                    //
                    // Avoid files like .au3Old because the above filter gets 
                    // all extensions starting with .au3 and ending with anything. Dumb.
                    //
                    if (s.EndsWith("au3") || s == "Open View" || s == "Sleep" || s == "Copy String To Clipboard")
                    {
                        this.ActionBuilderAdd_ComboBox.Items.Add(Path.GetFileNameWithoutExtension(s));
                    }
                }
            }
            else
            {
                MessageBox.Show("Unable to locate the .\\AutoIt\\Scripts folder. This is a critical failure. WinClickPro expects to find these folders within the working directory.");
                return;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        private void InitDataGrid()
        {
            g_dt.Columns.Add("Action");
            g_dt.Columns.Add("Timeout");
            g_dt.Columns.Add("Arg1");
        }
        /// <summary>
        /// Parse the xml document and extract the actions for the given tile
        /// </summary>
        private void LoadTilesSavedActions()
        {
            XmlNodeList xmlNodeList_View = g_xmlDocument.DocumentElement.GetElementsByTagName("view");
            foreach (XmlNode view in xmlNodeList_View)
            {
                if (view.FirstChild.InnerText == g_sCurrentViewID)
                {
                    foreach (XmlNode tile in view)
                    {
                        if (tile == null || tile.Name.Length == 0)
                        {
                            MessageBox.Show("WinClickPro - Fatal error occured while reading WinClickPro.xml (" + tile.Name + ")");
                            Environment.Exit(0);
                        }
                        if (tile.Name == "tile")
                        {
                            if (tile.FirstChild.Name == "id" && tile.FirstChild.InnerText == g_sTileName)
                            {
                                foreach (XmlNode actions in tile)
                                {
                                    if (actions == null)
                                    {
                                        MessageBox.Show("WinClickPro - Fatal error occured while reading WinClickPro.xml (" + tile.Name + ")");
                                        Environment.Exit(0);
                                    }
                                    if (actions.Name == "actions")
                                    {
                                        foreach (XmlNode action in actions)
                                        {
                                            if (action == null)
                                            {
                                                MessageBox.Show("WinClickPro - Fatal error occured while reading WinClickPro.xml (" + actions.Name + ")");
                                                Environment.Exit(0);
                                            }
                                            if (action.Name == "action")
                                            {
                                                int iArgCount = 1;
                                                DataRow dr = g_dt.NewRow();
                                                foreach (XmlNode actionParams in action)
                                                {
                                                    if (actionParams == null)
                                                    {
                                                        MessageBox.Show("WinClickPro - Fatal error occured while reading WinClickPro.xml (" + action.Name + ")");
                                                        Environment.Exit(0);
                                                    }

                                                    //
                                                    // type needs to come before timeout
                                                    //
                                                    if (actionParams.Name == "type" && actionParams.InnerText.Length > 0)
                                                    {
                                                        dr["Action"] = actionParams.InnerText;
                                                        continue;
                                                    }

                                                    //
                                                    // timeout needs to come before args
                                                    //
                                                    if (actionParams.Name == "timeout" && actionParams.InnerText.Length > 0)
                                                    {
                                                        dr["Timeout"] = actionParams.InnerText;
                                                        continue;
                                                    }

                                                    //
                                                    // Adding additional args and columns as nessecary
                                                    //
                                                    if (actionParams.Name == "arg")
                                                    {
                                                        // Arg1 is always there so only add a new column when exceeding Arg1
                                                        if (iArgCount > 1)
                                                        {
                                                            // This will start off with Arg2 because we skip the first time,
                                                            // and increment down below.
                                                            string sNextColumn = "Arg" + iArgCount.ToString();
                                                            if (!g_dt.Columns.Contains(sNextColumn))
                                                            {
                                                                g_dt.Columns.Add(sNextColumn);
                                                            }
                                                        }
                                                        dr["Arg" + (iArgCount++).ToString()] = actionParams.InnerText;
                                                    }
                                                }
                                                if (dr.ItemArray.Length > 0)
                                                {
                                                    g_dt.Rows.Add(dr);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            this.ActionBuilder_DataGridView.DataSource = g_dt;
        }
        /// <summary>
        /// Add action to datagrid
        /// </summary>
        private void ActionBuilderAdd_Button_Click(object sender, EventArgs e)
        {
            if (this.ActionBuilderAdd_ComboBox.SelectedItem != null)
            {
                DataRow dr = null;
                switch (this.ActionBuilderAdd_ComboBox.SelectedItem.ToString())
                {
                    case "Copy String To Clipboard":
                        {
                            dr = g_dt.NewRow();
                            dr["Action"] = "Copy String To Clipboard";
                            dr["Timeout"] = 0;
                            dr["Arg1"] = "";
                            break;
                        }
                     case "Open View":
                        {
                            dr = g_dt.NewRow();
                            dr["Action"] = "Open View";
                            dr["Timeout"] = 0;
                            dr["Arg1"] = Guid.NewGuid().ToString();
                            break;
                        }
                    case "Sleep":
                        {
                            dr = g_dt.NewRow();
                            dr["Action"] = "Sleep";
                            dr["Timeout"] = 0;
                            dr["Arg1"] = 5000;
                            break;
                        }
                    default:
                        {
                            dr = g_dt.NewRow();
                            dr["Action"] = this.ActionBuilderAdd_ComboBox.SelectedItem.ToString();
                            dr["Timeout"] = 5000;
                            break;
                        }
                }
                if (dr != null && dr.ItemArray.Length > 0)
                {
                    g_dt.Rows.Add(dr);
                }

                this.ActionBuilder_DataGridView.DataSource = g_dt;
            }
        }
        /// <summary>
        /// Prompts the user to provide a tile name which we then apply.
        /// </summary>
        private string SetTileName(string sOldName)
        {
            string sResult = GetInputDialog("Tile Text", sOldName, false);
            return sResult;
        }
        private void ActionBuilderCancel_Button_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        /// <summary>
        /// Commit datagrid data to xml save file.
        /// </summary>
        private void ActionBuilderOK_Button_Click(object sender, EventArgs e)
        {
            bool bIsCanceled = false;
            // Don't save anything. Could the user try to clear a tile without deleting it for some reason. Just delete it
            // and create a new one without assigning anything? Possible usability issue.
            if (g_dt.Rows.Count > 0)
            {
                XmlNodeList xmlViews = g_xmlDocument.DocumentElement.GetElementsByTagName("view");
                foreach (XmlNode xmlView in xmlViews)
                {
                    if (xmlView.FirstChild.InnerText == g_sCurrentViewID)
                    {
                        foreach (XmlNode xmlTile in xmlView)
                        {
                            if (xmlTile == null)
                            {
                                MessageBox.Show("WinClickPro - Fatal error occured while reading WinClickPro.xml (" + xmlView.Name + ")");
                                Environment.Exit(0);
                            }
                            if (xmlTile.Name == "tile" && xmlTile.FirstChild.InnerText == g_sTileName)
                            {
                                XmlNode xmlTileText = xmlTile.SelectSingleNode("text");
                                // If the user cancels the name dialog, skip.
                                string sTileNameResult = SetTileName(xmlTileText.InnerText);
                                if (sTileNameResult != "canceled")
                                {
                                    xmlTileText.InnerText = sTileNameResult;
                                }
                                else
                                {
                                    bIsCanceled = true;
                                    break;
                                }
                                XmlNode xmlAction = xmlTile.SelectSingleNode("actions");
                                //
                                // Odd thing to do here.
                                //
                                if (xmlAction != null)
                                {
                                    xmlAction.RemoveAll();
                                }
                                foreach (DataRow dr in g_dt.Rows)
                                {
                                    // action
                                    XmlElement xmlChildElement = g_xmlDocument.CreateElement("action");
                                    xmlAction.AppendChild(xmlChildElement);

                                    // Replace actions with action node
                                    XmlElement xmlParentElement = xmlChildElement;

                                    // type
                                    xmlChildElement = g_xmlDocument.CreateElement("type");
                                    XmlText xmlText = g_xmlDocument.CreateTextNode(dr[0].ToString());
                                    xmlParentElement.AppendChild(xmlChildElement);
                                    xmlParentElement.LastChild.AppendChild(xmlText);

                                    // timeout
                                    xmlChildElement = g_xmlDocument.CreateElement("timeout");
                                    xmlText = g_xmlDocument.CreateTextNode(dr[1].ToString());
                                    
                                    try
                                    {
                                        UInt32 iTimeout = Convert.ToUInt32(dr[1].ToString()); // Must be 0 or positive
                                    }
                                    catch(Exception)
                                    {
                                        MessageBox.Show("Invalid Timeout value specified for Action: " + dr[0].ToString() + "\nThe Timeout must be 0 or positive (5000).");
                                        bIsCanceled = true;
                                        break;
                                    }

                                    xmlParentElement.AppendChild(xmlChildElement);
                                    xmlParentElement.LastChild.AppendChild(xmlText);

                                    //
                                    // Loop through and add all args
                                    // Args start after the Action and Timeout columns (2)
                                    //
                                    for (int i = 2; i < dr.ItemArray.Length; i++)
                                    {
                                        xmlChildElement = g_xmlDocument.CreateElement("arg");
                                        xmlText = g_xmlDocument.CreateTextNode(@dr[i].ToString());
                                        xmlParentElement.AppendChild(xmlChildElement);
                                        xmlParentElement.LastChild.AppendChild(xmlText);
                                    }
                                }
                                // We updated the tile, we can get out.
                                break;
                            }
                        }
                        // We updated the tile, we can get out.
                        break;
                    }
                }
                if (!bIsCanceled)
                {
                    g_xmlDocument.Save(Application.StartupPath + "\\WinClickPro.xml");
                }
            }
            if (!bIsCanceled)
            {
                this.Close();
            }
        }
        /// <summary>
        /// Removes a line from the Action Builder
        /// </summary>
        private void ActionBuilderRemove_Button_Click(object sender, EventArgs e)
        {
            //
            //
            //
            if (ActionBuilder_DataGridView.SelectedRows.Count > 0)
            {
                while (ActionBuilder_DataGridView.SelectedRows.Count > 0)
                {
                    // If this is the last row (Create new row... row), skip.
                    if (ActionBuilder_DataGridView.SelectedRows[0].Index != g_dt.Rows.Count)
                    {
                        g_dt.Rows[ActionBuilder_DataGridView.SelectedRows[0].Index].Delete();
                    }
                    else
                    {
                        break;
                    }
                }
            }
            else
            {
                while (ActionBuilder_DataGridView.SelectedCells.Count > 0)
                {
                    ActionBuilder_DataGridView.Rows[ActionBuilder_DataGridView.SelectedCells[0].RowIndex].Cells[ActionBuilder_DataGridView.SelectedCells[0].ColumnIndex].Value = String.Empty;
                    ActionBuilder_DataGridView.Rows[ActionBuilder_DataGridView.SelectedCells[0].RowIndex].Cells[ActionBuilder_DataGridView.SelectedCells[0].ColumnIndex].Selected = false;
                }
            }
        }
        /// <summary>
        /// Swaps a row with the row above it.
        /// </summary>
        private void ActionBuilderUp_Button_Click(object sender, EventArgs e)
        {
            //
            // Loop through the selected rows.
            //
            foreach (DataGridViewRow SelectedRow in ActionBuilder_DataGridView.SelectedRows)
            {
                int xRow = (int)ActionBuilder_DataGridView.Rows.IndexOf(SelectedRow);
                //
                // Don't move rows beyond the ends of the datagrid
                //
                if (xRow > 0 && xRow != ActionBuilder_DataGridView.Rows.Count - 1)
                {
                    DataGridViewRow firstRow = this.ActionBuilder_DataGridView.Rows[xRow - 1];
                    DataGridViewRow nextRow = this.ActionBuilder_DataGridView.Rows[xRow];

                    //Create a temporary value
                    Object temp;
                    Object temp2;
                    //
                    // Loop through each cell in the firstRow datagridview
                    //
                    for (int i = 0; i < firstRow.Cells.Count; i++)
                    {
                        //
                        // If the cell isn't read only, then swap them.
                        //
                        if (firstRow.Cells[i].ReadOnly == false)
                        {
                            //
                            // use the temp object to swap the cell values.
                            //
                            temp = firstRow.Cells[i].Value;
                            temp2 = nextRow.Cells[i].Value;

                            firstRow.Cells[i].Value = temp2;
                            nextRow.Cells[i].Value = temp;
                        }
                    }

                    // Renable moves after valid moves.
                    ActionBuilder_DataGridView.Rows[xRow - 1].Cells[0].Selected = true;
                    ActionBuilder_DataGridView.Rows[xRow - 1].Selected = true;
                    this.ActionBuilderUp_Button.Enabled = true;
                    this.ActionBuilderDown_Button.Enabled = true;
                }
            }
        }
        /// <summary>
        /// Swaps a row with the row below it.
        /// </summary>
        private void ActionBuilderDown_Button_Click(object sender, EventArgs e)
        {
            //
            //
            //
            foreach (DataGridViewRow SelectedRow in ActionBuilder_DataGridView.SelectedRows)
            {
                int xRow = (int)ActionBuilder_DataGridView.Rows.IndexOf(SelectedRow);
                //
                //
                //
                if (xRow < ActionBuilder_DataGridView.Rows.Count - 2)
                {
                    DataGridViewRow firstRow = this.ActionBuilder_DataGridView.Rows[xRow + 1];
                    DataGridViewRow nextRow = this.ActionBuilder_DataGridView.Rows[xRow];

                    //Create a temporary value
                    Object temp;
                    Object temp2;

                    //
                    // Loop through each cell in the firstRow datagridview
                    //
                    for (int i = 0; i < firstRow.Cells.Count; i++)
                    {
                        //
                        // If the cell isn't read only, then swap them.
                        //
                        if (firstRow.Cells[i].ReadOnly == false)
                        {
                            //
                            // use the temp object to swap the cell values.
                            //
                            temp = firstRow.Cells[i].Value;
                            temp2 = nextRow.Cells[i].Value;

                            firstRow.Cells[i].Value = temp2;
                            nextRow.Cells[i].Value = temp;
                        }
                    }
                    //
                    // Renable moves after valid moves.
                    //
                    if (xRow > -1)
                    {
                        ActionBuilder_DataGridView.Rows[xRow + 1].Cells[0].Selected = true;
                        ActionBuilder_DataGridView.Rows[xRow + 1].Selected = true;
                        this.ActionBuilderUp_Button.Enabled = true;
                        this.ActionBuilderDown_Button.Enabled = true;
                    }
                }
            }
        }
        /// <summary>
        /// Sets the up and down arrows to enabled
        /// </summary>
        private void ActionBuilder_DataGridView_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            this.ActionBuilderUp_Button.Enabled = true;
            this.ActionBuilderDown_Button.Enabled = true;
        }
        /// <summary>
        /// Sets the up and down buttons to disabled
        /// </summary>
        private void ActionBuilder_DataGridView_SelectionChanged(object sender, EventArgs e)
        {
            this.ActionBuilderUp_Button.Enabled = false;
            this.ActionBuilderDown_Button.Enabled = false;
        }
        /// <summary>
        /// Opens a dialog and prompts the user to provide a string
        /// Used for getting the title of a new view
        /// Used for getting the file path from opening a folder
        /// Sets certain controls on the form to be visible and even 
        /// changes position and lengths of controls to match the needs of 
        /// the request.
        /// </summary>
        private static string GetInputDialog(string sRequestType, string sOldValue, bool bIsImageSearch)
        {
            string sResult = string.Empty;
            GetInputDialog oGetInputDialog = new GetInputDialog();
            oGetInputDialog.TopMost = true;
            oGetInputDialog.CancelButton2.Visible = true; // Reset in case previous call made invisible

            //
            // Used to have more options but the conversion to AutoIt removed the need.
            //
            switch (sRequestType)
            {
                case "Tile Text":
                    {
                        oGetInputDialog.GetInputDialogLabel.Text = "Tile Text:";
                        oGetInputDialog.Text = " Tile Text";
                        oGetInputDialog.TextBox_Input.Text = sOldValue;
                        oGetInputDialog.CancelButton2.Visible = true;
                        break;
                    }
                default:
                    {
                        MessageBox.Show("WinClickPro - Wrong sRequestType (" + sRequestType + ") passed into GetInputDialog()");
                        break;
                    }
            }
            if (oGetInputDialog.ShowDialog() == DialogResult.OK)
            {
                sResult = oGetInputDialog.TextBox_Input.Text.Trim();
                // This checks to see if the user provided a blurb to copy.
                if (sResult.Length == 0 && oGetInputDialog.TextBox_Input.Lines.Length > 0)
                {
                    oGetInputDialog.TextBox_Input.SelectAll();
                    sResult = oGetInputDialog.TextBox_Input.Lines[0].ToString();
                }
            }
            else
            {
                sResult = "canceled";
            }
            return sResult;
        }
        /// <summary>
        /// Adds an additional column to the table for each press
        /// </summary>
        private void AddColumn_Button_Click(object sender, EventArgs e)
        {
            string sLastColumnName = g_dt.Columns[g_dt.Columns.Count-1].ColumnName;
            string[] arrDelimiters = new string[1] { "Arg" };
            string[] splitColumnName = sLastColumnName.Split(arrDelimiters, StringSplitOptions.RemoveEmptyEntries);
            string sNewColumnName = "Arg" + (Convert.ToInt32(splitColumnName[0]) + 1).ToString();
            g_dt.Columns.Add(sNewColumnName);
        }
        /// <summary>
        /// Deletes the last Arg column from the grid
        /// </summary>
        private void DelArg_Button_Click(object sender, EventArgs e)
        {
            string sLastColumnName = g_dt.Columns[g_dt.Columns.Count - 1].ColumnName;
            //
            // Don't let user remove non-arg columns and always leave one arg column.
            //
            if (g_dt.Columns.Count > 3)
            {
                g_dt.Columns.Remove(sLastColumnName);
            }
        }
        /// <summary>
        /// Launches the AutoIt CHM file to whatever keyword is provided in the DDL. Example if "ProcessClose" is selected, 
        /// the user will be navigated to that topic in the .chm file. 
        /// </summary>
        private void AutoItHelp_Button_Click(object sender, EventArgs e)
        {
            // MessageBox.Show(g_AutoItProcess.ExitCode.ToString());
            //
            // Clicking MoreInfo without an item select results in a NULL selectedItem
            //
            if (this.ActionBuilderAdd_ComboBox.SelectedItem != null)
            {
                string sSelectedAction = this.ActionBuilderAdd_ComboBox.SelectedItem.ToString();
                //
                // Handle backed in actions or pass along to AutoIt scripts.
                //
                switch (sSelectedAction)
                {
                    case "Copy String To Clipboard":
                        {
                            MessageBox.Show("Copy String To Clipboard - Copies the specified string to the clipboard.\r\n\r\nArguments: [1 Required, 0 Optional]\r\n\r\n    Required: \r\n        <Arg1> String\r\n            - User specified string to copy to clipboard.\r\n", "More Info", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                            break;
                        }
                    case "Open View":
                        {
                            MessageBox.Show("Open View - Closes the current view and opens a new one.\r\n\r\nArguments: [1 Required, 0 Optional]\r\n\r\n    Required: \r\n        <Arg1> Name of view\r\n            - A random name is automatically generated for the view but it can be changed.\r\n", "More Info", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                            break;
                        }
                    case "Sleep":
                        {
                            MessageBox.Show("Sleep - Waits for the specified amount of time before calling the next action.\r\n\r\nArguments: [1 Required, 0 Optional]\r\n\r\n    Required: \r\n        <Arg1> Time\r\n            - The time to wait in milliseconds. The default is 5000 (5 seconds).", "More Info", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                            break;
                        }
                    default:
                        {
                            string sAutoItHelp = String.Empty;
                            //
                            // Must have an action selected
                            //
                            if (this.ActionBuilderAdd_ComboBox.SelectedItem != null)
                            {
                                //
                                // Sanity check
                                //
                                if (File.Exists(".\\AutoIt\\Scripts\\" + this.ActionBuilderAdd_ComboBox.SelectedItem.ToString() + ".au3"))
                                {
                                    string[] readText = File.ReadAllLines(".\\AutoIt\\Scripts\\" + this.ActionBuilderAdd_ComboBox.SelectedItem.ToString() + ".au3");
                                    bool bIsProcessingArgsComments = false;
                                    foreach (string s in readText)
                                    {
                                        if (!bIsProcessingArgsComments && s == "#comments-start - Args Dialog")
                                        {
                                            bIsProcessingArgsComments = true;
                                        }
                                        //
                                        // Are we done?
                                        //
                                        if (s == "#comments-end - Args Dialog")
                                        {
                                            break;
                                        }
                                        //
                                        // We are processing the Arg Comments
                                        //
                                        if (s.StartsWith("[AutoIt Help]"))
                                        {
                                            sAutoItHelp = s.Substring(13); // Everything after [Title]
                                        }
                                    }
                                    //
                                    // In some cases, it doesn't make a lot of sense to provide a single
                                    // help reference since the script may use many. In thoses cases,
                                    // refer the user to the actual script to learn more about it.
                                    //
                                    if (sAutoItHelp.Trim() == String.Empty)
                                    {
                                        MessageBox.Show("AutoIt Help is not available for this script. Please review the script to learn more about how it works.", "AutoIt Help", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                                    }
                                    else
                                    {
                                        Help.ShowHelp(this, ".\\AutoIt\\AutoIt.chm", HelpNavigator.KeywordIndex, sAutoItHelp);
                                    }
                                }
                                else
                                {
                                    MessageBox.Show("Unable to locate AutoIt script! Please make sure the file exists and try again.", "AutoIt Help", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                                }
                            }
                            else
                            {
                                MessageBox.Show("Please select an action from the dropdown list and then try again.", "AutoIt Help", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                            }
                            
                            break;
                        }
                }
            }
            else
            {
                MessageBox.Show("Please select an action from the dropdown list and then try again.", "AutoIt Help", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
            }
        }
        /// <summary>
        /// User clicks More Info button to get information about the selected action.
        /// </summary>
        private void Button_MoreInfo_Click(object sender, EventArgs e)
        {
            string sTitle = String.Empty;
            List<string> sListOfArgs = new List<string>();
            MoreInfo mi = new MoreInfo();
            
            string sComments = "";
            if (this.ActionBuilderAdd_ComboBox.SelectedItem != null)
            {
                if (this.ActionBuilderAdd_ComboBox.SelectedItem.ToString() == "Copy String To Clipboard")
                {
                    sComments = "Description:\n";
                    sComments += "    - Copies the user specified string to the clipboard.\n";
                    sComments += "        - Notes: \n";
                    sComments += "            - Copy String To Clipboard is an internal action. There is no script for it.\n\n";
                    sComments += "Arguments:\n";
                    sComments += "    - Args1: String\n";
                    sComments += "        - Notes:\n";
                    sComments += "            - A fast and easy way to copy strings like URLS, network paths, folder paths, build numbers, and etc";
                }
                else if (this.ActionBuilderAdd_ComboBox.SelectedItem.ToString() == "Open View")
                {
                    sComments = "Description:\n";
                    sComments += "    - Create an all new view to organize new tiles.\n";
                    sComments += "        - Notes: \n";
                    sComments += "            - Open View is an internal action. There is no script for it.\n\n";
                    sComments += "Arguments:\n";
                    sComments += "    - Args1: Unique name of view.\n";
                    sComments += "        - Notes:\n";
                    sComments += "            - By default the name is a random GUID but you can change it. Changing\n";
                    sComments += "              it can be useful if you are working on navigating between a number\n";
                    sComments += "              of different views. You could do things like make back buttons.\n";
                    sComments += "            - It's also important to note that your initial view is named 0 and cannot be changed.\n";

                    //MessageBox.Show(sComments, "Open View", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                }
                else if (this.ActionBuilderAdd_ComboBox.SelectedItem.ToString() == "Sleep")
                {
                    sComments = "Description:\n";
                    sComments += "    - Sleep for the specified amount of time before calling the next Action.\n";
                    sComments += "        - Notes: \n";
                    sComments += "            - Sleep is an internal action. There is no script for it.\n";
                    sComments += "            - Sleep delays execution while Timeout ends execution\n";
                    sComments += "            - The Timeout column does not apply when using Sleep.\n\n";
                    sComments += "Arguments:\n";
                    sComments += "    - Args1: Time in milliseconds.\n";
                    sComments += "        - Example:\n";
                    sComments += "            - 250 is 1/4 of a second.\n";
                    sComments += "            - 1000 is 1 second.\n";
                    sComments += "            - 5000 is 5 seconds.\n";
                    sComments += "            - 60000 is 1 minute.\n";
                   //MessageBox.Show(sComments, "Open View", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                }
                //
                // Sanity check
                //
                else if (File.Exists(".\\AutoIt\\Scripts\\" + this.ActionBuilderAdd_ComboBox.SelectedItem.ToString() + ".au3"))
                {
                    string[] readText = File.ReadAllLines(".\\AutoIt\\Scripts\\" + this.ActionBuilderAdd_ComboBox.SelectedItem.ToString() + ".au3");
                    bool bIsProcessingArgsComments = false;
                    foreach (string s in readText)
                    {
                        if (!bIsProcessingArgsComments && s == "#comments-start - More Info Dialog")
                        {
                            bIsProcessingArgsComments = true;
                            continue;
                        }
                        //
                        // Are we done?
                        //
                        if (s == "#comments-end - More Info Dialog")
                        {
                            break;
                        }
                        //
                        // We are processing the Arg Comments
                        //
                        if (s.StartsWith("[SCRIPT NAME]")) // Don't forget to change the the next line if you alter this name.
                        {
                            sTitle = s.Substring(13).Trim(); // Everything after [SCRIPT NAME]
                        }
                        else
                        {
                            sListOfArgs.Add(s); // Add everyline until we exit the comment block.
                        }
                    }
                    
                    //
                    // Collect all lines in the comments section
                    //
                    for(int i = 0; i < sListOfArgs.Count; i++)
                    {
                        sComments += sListOfArgs[i] + "\n";
                    }

                    //MessageBox.Show(sComments, sTitle, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                }
                else
                {
                    MessageBox.Show("Unable to locate AutoIt script! Please make sure the file exists and try again.", "More Info", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                }

                mi.Controls["RichTextBox_MoreInfo"].Text = sComments;
                mi.Show();
            }
            else
            {
                MessageBox.Show("Please select an action from the dropdown list and then try again.", "More Info", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
            }
        }

        private void Button_Help_Click(object sender, EventArgs e)
        {
            MoreInfo mi = new MoreInfo();
            string sMessage = "";
            sMessage += "- [More Info]: Provides more information about the current selected Action.\n";
            sMessage += "- [Add]: Adds the currently selected action to the action grid.\n";
            sMessage += "- [Remove]: Removes the currently selected row from the action grid.\n";
            sMessage += "- [Add Arg]: Adds an additional Arg column.\n";
            sMessage += "- [Del Arg]: Removes the last Arg column.\n";
            sMessage += "- [Up]: Moves the currently selected row upwards in the action grid.\n";
            sMessage += "- [Down]: Moves the currently selected row downward in the action grid.\n\n";
            sMessage += "- Action Column: Lists the actions in order of execution. \n";
            sMessage += "      Note: Actions which return a fail code halt execution of remaining actions which have not been executed yet.\n\n";
            sMessage += "- Timeout Column: Lists the timeout for each action.\n";
            sMessage += "      Notes:\n";
            sMessage += "          Generally speaking, leave it as the default (5000) for most operations\n";
            sMessage += "      Options:\n";
            sMessage += "          0 - Execute this action and then execute the next without waiting.\n";
            sMessage += "              Notes: Be careful with this option. All scripts get executed in order but there is no guarantee which will finish first or even run first.\n\n";
            sMessage += "              Example: \n";
            sMessage += "                  Use SendKeys to send \"abc\" to note pad with a Timeout of 0 and this is what you might get: acb. \n\n";
            sMessage += "          <int> - Specify a timeout in milliseconds.\n";
            sMessage += "              Notes: Actions which timeout pause execution and wait for user input before continuing. The default is 5000 seconds but most actions will return almost immediately. Any invalid value including blank will result in the default 5000 seconds. Reducing the timeout will not speed up the execution of the script.\n\n";
            sMessage += "- Args Column(s): User defined columns which can be added and removed.\n";
            sMessage += "      Notes: When creating chained actions (process of adding more than one action to the action grid), make sure to match the Arg column names to the specific Args seen in More Info. Empty columns use default values or are ignored altogether. Booleans and any predefined keywords are typically case insensative so things like \"tRue\" work fine.";
            
            mi.Controls["RichTextBox_MoreInfo"].Text = sMessage;
            mi.Show();
        }
    }
}

